<?php

/**
 * 命令模式：将操作封装在对象中。关键思想是提供将客户机和接收方解耦的方法
 * Class Command
 */

/**
 * client通过Invoker调用Command命令。
 * Command定义了相关操作
 */


class Bulb
{
    public function turnOn()
    {
        echo "Bulb has been lit";
    }

    public function turnOff()
    {
        echo "Darkness";
    }
}

// command
interface Command
{
    public function execute();

    public function undo();

    public function redo();
}

class TurnOn implements Command
{
    protected $bulb;

    public function __construct(Bulb $bulb)
    {
        $this->bulb = $bulb;
    }

    public function execute()
    {
        $this->bulb->turnOn();
    }

    public function undo()
    {
        $this->bulb->turnOff();
    }

    public function redo()
    {
        $this->execute();
    }
}


class TurnOff implements Command
{
    protected $bulb;

    public function __construct(Bulb $bulb)
    {
        $this->bulb = $bulb;
    }

    public function execute()
    {
        $this->bulb->turnOff();
    }

    public function undo()
    {
        $this->bulb->turnOn();
    }

    public function redo()
    {
        $this->execute();
    }
}

//Invoker
class RemoteControl
{
    public function submit(Command $command)
    {
        $command->execute();
    }
}

// usage
$bulb = new Bulb();
// command
$turnOn = new TurnOn($bulb);
$turnOff = new TurnOff($bulb);
// invoker
$remote = new RemoteControl();
$remote->submit($turnOn);
$remote->submit($turnOff);